package ch.netcetera.planningpoker.client.ui.admin.create;

import java.util.logging.Logger;

import ch.netcetera.planningpoker.client.model.GameProxy;
import ch.netcetera.planningpoker.client.ui.admin.moderate.ModerationPresenter;
import ch.netcetera.planningpoker.client.ui.main.MainPagePresenter;
import ch.netcetera.planningpoker.shared.GameRequest;
import ch.netcetera.planningpoker.shared.GameRequestFactory;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.HasKeyUpHandlers;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasVisibility;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.ServerFailure;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;

public class CreateGamePresenter extends
        Presenter<CreateGamePresenter.IView, CreateGamePresenter.IProxy> {

    private static final Logger logger = Logger
            .getLogger(CreateGamePresenter.class.getName());

    public static final String NAME_TOKEN = "create";

    @ProxyCodeSplit
    @NameToken("create")
    public interface IProxy extends ProxyPlace<CreateGamePresenter> {

    }

    public interface IView extends View {

        HasClickHandlers getCreateGame();

        HasKeyUpHandlers getGameNameForEnter();

        HasText getGameName();

        void setWaiting(boolean isWaiting);

        HasVisibility getValidationWarning();
    }

    private GameRequestFactory requestFactory;
    private PlaceManager placeManager;

    @Inject
    public CreateGamePresenter(EventBus eventBus, PlaceManager placeManager,
            IView view, IProxy proxy, GameRequestFactory requestFactory) {
        super(true, eventBus, view, proxy);
        this.requestFactory = requestFactory;
        this.placeManager = placeManager;
    }

    @Override
    protected void onBind() {
        getView().getCreateGame().addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                createGameIfTitleUnique();
            }
        });
        getView().getGameNameForEnter().addKeyUpHandler(new KeyUpHandler() {

            @Override
            public void onKeyUp(KeyUpEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    createGameIfTitleUnique();
                }
            }
        });
    }

    private void createGameIfTitleUnique() {
        final String gameName = getView().getGameName().getText();
        logger.info("Create pressed. Game name: " + gameName);

        GameRequest gameRequest = requestFactory.getGameRequest();
        getView().setWaiting(true);
        gameRequest.isGameExisting(gameName).fire(new Receiver<Boolean>() {

            @Override
            public void onFailure(ServerFailure error) {
                getView().setWaiting(false);
                super.onFailure(error);
            }

            @Override
            public void onSuccess(Boolean isTitleExisting) {
                getView().setWaiting(false);
                if (isTitleExisting) {
                    logger.info("The chosen title " + gameName
                            + " has been used before.");
                    getView().getValidationWarning().setVisible(true);
                } else {
                    logger.info("The chosen title " + gameName
                            + " is new. Creating game");
                    createGame(gameName);
                }
            }

        });
    }

    private void createGame(String gameName) {
        GameRequest gameRequest = requestFactory.getGameRequest();
        GameProxy game = gameRequest.create(GameProxy.class);
        game.setTitle(gameName);
        logger.info("Sending the createGame request");
        gameRequest.persistGame(game).fire(new Receiver<Long>() {

            @Override
            public void onSuccess(Long id) {
                logger.info("Succeded to create game with id: " + id);

                PlaceRequest request = new PlaceRequest(
                        ModerationPresenter.NAME_TOKEN).with(
                        ModerationPresenter.ARG_GAME_ID, String.valueOf(id));

                placeManager.revealPlace(request, true);
            }

        });
    }

    @Override
    protected void revealInParent() {
        RevealContentEvent.fire(this, MainPagePresenter.MainContentSlot, this);
    }

}
